﻿// <copyright file="LogProvider.cs" company="Ecole Normale Supérieure">
// Released under GPLv2
// </copyright>
// <summary>Contains the LogProvider provider</summary>

namespace Sqwarea.Persistence.Azure
{
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Linq;
    using Lokad.Cloud.Storage;

    /// <summary>
    /// Provider for logs
    /// </summary>
    public class LogProvider : ILogProvider
    {
        /// <summary>
        /// Name of the table Storing the logs
        /// </summary>
        public const string LogTableName = "sqwarealogtable";

        /// <summary>
        /// table provider
        /// </summary>
        private readonly ITableStorageProvider _tableProvider;

        /// <summary>
        /// Initializes a new instance of the LogProvider class.
        /// </summary>
        /// <param name="tableProvider"> a table provider</param>
        [CLSCompliantAttribute(false)]
        public LogProvider(ITableStorageProvider tableProvider)
        {
            if (null == tableProvider)
            {
                throw new ArgumentNullException("tableProvider", "tableProvider must not be null");
            }

            _tableProvider = tableProvider;
            _tableProvider.CreateTable(LogTableName);
        }

        /// <summary>
        /// Saves or Update a log.
        /// Beware of the "UniqueId" component of the log : 
        /// creating two logs with exactly the same parameters will still create two different logs.
        /// </summary>
        /// <param name="log">The log to be saved or Updated.</param>
        public void StoreLog(Log log)
        {
            var logEntity = new CloudEntity<Log>
                                {
                                    Value = log,
                                    PartitionKey = log.KingId.ToString(Tools.NumberFormat),
                                    RowKey =
                                        log.Date.ToString(GameProvider.GameDateFormat, CultureInfo.InvariantCulture) +
                                        log.UniqueId
                                };

            CloudEntity<Log>[] logList = { logEntity };
            _tableProvider.Upsert(LogTableName, logList);
        }
        
        /// <summary>
        /// Deletes the logs given in parameter from the Log table
        /// All given logs must have the same KingId
        /// </summary>
        /// <param name="logs">list of logs to be removed from the Table</param>
        public void DeleteLogs(IEnumerable<Log> logs)
        {
            var first = logs.FirstOrEmpty();
            if (!first.HasValue)
            {
                return;
            }

            string partitionKey = first.Value.KingId.ToString(Tools.NumberFormat);
            IEnumerable<string> rowKeys = logs
                .Where(log => log.KingId.ToString(Tools.NumberFormat) == partitionKey)
                .Select(log => log.Date.ToString(GameProvider.GameDateFormat, CultureInfo.InvariantCulture) +
                               log.UniqueId);
            _tableProvider.Delete<Log>(LogTableName, partitionKey, rowKeys);
        }

        /// <summary>
        /// Gets the logs of kingId user.
        /// </summary>
        /// <param name="kingId">Id of the required king</param>
        /// <returns>See summary</returns>
        public IEnumerable<Log> GetLogs(long kingId)
        {
            var logs = _tableProvider.Get<Log>(LogTableName, kingId.ToString(Tools.NumberFormat));
            return from log in logs
                   orderby log.RowKey descending
                   select log.Value;
        }
    }
}
